package cn.dengta.webapp.im.dto;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

import cn.dengta.common.model.TimeInterval;
import cn.dengta.context.model.WesKit;
import cn.dengta.webapp.im.entity.UserActiveReward;
import cn.dengta.webapp.trade.dto.FemaleIncomeTaskConfig;
import cn.dengta.webapp.user.model.Gender;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import me.codeplayer.util.X;

/**
 * 用户活跃奖励任务配置
 *
 * @author XiaoRong
 * @since 2022/12/27
 */
@Getter
@Setter
@Accessors(chain = true)
public class UserActiveTaskDTO implements Serializable {

	/** 男用户任务配置 */
	private TaskConfig maleTaskConfig;
	/** 女用户任务配置 */
	private TaskConfig femaleTaskConfig;
	/** 女用户收益任务 */
	private FemaleIncomeTaskConfig femaleIncomeTaskConfig;

	/** 男用户连续视频配置 */
	ConsecutiveConfig maleConsecutiveConfig;
	/** 女用户连续视频配置 */
	ConsecutiveConfig femaleConsecutiveConfig;

	public ConsecutiveConfig getMaleConsecutiveConfig() {
		return X.getElse(maleConsecutiveConfig, ConsecutiveConfig::getDefault);
	}

	public ConsecutiveConfig getFemaleConsecutiveConfig() {
		return X.getElse(femaleConsecutiveConfig, ConsecutiveConfig::getDefault);
	}

	public static UserActiveTaskDTO initDefault() {
		UserActiveTaskDTO dto = new UserActiveTaskDTO();
		dto.setFemaleTaskConfig(new TaskConfig(1200, BigDecimal.valueOf(90), 120, 200));
		dto.setMaleTaskConfig(new TaskConfig(50, BigDecimal.valueOf(10), 60, 80));
		dto.setFemaleIncomeTaskConfig(FemaleIncomeTaskConfig.getDefault());
		return dto;
	}

	@Getter
	@Setter
	public static class TaskConfig implements Serializable {

		/** 是否开启 */
		private Boolean enable;
		/** 视频池一，仅针对女用户 */
		private List<VideoPoolReward> videoPoolReward1;
		/** 视频池二,是否开启 仅针对女用户 */
		private Boolean videoPool2Enable;
		/** 进入条件（分钟） */
		private Integer videoPool2JoinTime;
		/** 基础视频天数 */
		private Integer videoPool2BaseTime;
		/** 基础奖励 */
		private Integer videoPool2BaseRewardNum;
		/** 视频池二，仅针对女用户 */
		private List<VideoPoolReward> videoPoolReward2;
		/** 梯度奖励 */
		private List<LadderReward> ladderRewards;
		/** 启用的分包,不在次Set中的，分包用户不结算 */
		private Set<WesKit> wesKitEnable;

		public TaskConfig() {
		}

		public TaskConfig(Integer greetTimes, BigDecimal reply, Integer onlineTime, Integer rewardNum) {
			LadderReward ladderReward = new LadderReward();
			ladderReward.setGreetTimes(greetTimes);
			ladderReward.setReply(reply);
			ladderReward.setOnlineTime(onlineTime);
			ladderReward.setRewardNum(rewardNum);
			this.ladderRewards = List.of(ladderReward);
			this.enable = false;
		}

		/**
		 * 梯度奖励
		 */
		@Setter
		@Getter
		public static class LadderReward {

			/** 搭讪次数 */
			private Integer greetTimes;
			/** 有效回复率、回复次数 */
			private BigDecimal reply;
			/** 在线时长（分钟） */
			private Integer onlineTime;
			/** 完成任务的奖励数量（男用户为金币、女用户为积分） */
			private Integer rewardNum;

		}

		/**
		 * 视频池奖励
		 */
		@Setter
		@Getter
		public static class VideoPoolReward {

			/** 门槛：时长门槛，百分比门槛 */
			private Integer threshold;
			/** 奖励积分 */
			private Integer rewardNum;

		}

		public List<VideoPoolReward> getVideoPoolReward1() {
			// 视频池1初始化时兜底
			if (videoPoolReward1 == null) {
				videoPoolReward1 = new ArrayList<>();
				videoPoolReward1.add(new VideoPoolReward().setThreshold(180).setRewardNum(50));
			}
			return videoPoolReward1;
		}

		public Boolean getVideoPool2Enable() {
			return videoPool2Enable != null && videoPool2Enable;
		}

		public VideoPoolReward calcNextReward(double percentage, boolean isPool2) {
			List<VideoPoolReward> taskConfig = isPool2 ? getVideoPoolReward2() : getVideoPoolReward1();
			VideoPoolReward last = null;
			for (VideoPoolReward videoPoolReward : taskConfig) {
				if (percentage < videoPoolReward.getThreshold()) {
					last = videoPoolReward;
					break;
				}
			}

			if (last == null) {
				last = taskConfig.get(taskConfig.size() - 1);
			}
			return last;
		}

		public VideoPoolReward calcReward(double percentage, boolean isPool2) {
			List<VideoPoolReward> taskConfig = isPool2 ? getVideoPoolReward2() : getVideoPoolReward1();
			VideoPoolReward last = null;
			for (VideoPoolReward videoPoolReward : taskConfig) {
				if (percentage >= videoPoolReward.getThreshold()) {
					last = videoPoolReward;
				} else {
					break;
				}
			}
			return last;
		}

		public LadderReward calcBaseReward(UserActiveReward active, Gender gender) {
			BigDecimal replyRate = null;
			if (Gender.isFemale(gender)) {
				if (active.getMsgTimes() > 0) {
					// 女用户回复率=当日有效回复次数/当日收到的消息数
					replyRate = BigDecimal.valueOf(active.getReplyTimes()).divide(new BigDecimal(active.getMsgTimes()), 2, RoundingMode.DOWN);
				} else {
					return null;
				}
			}

			LadderReward current = null;
			for (LadderReward ladderReward : getLadderRewards()) {
				// 男用户是人数，女用户是百分比
				boolean isReply = Gender.FEMALE == gender ? replyRate != null && replyRate.compareTo(ladderReward.getReply()) >= 0 : active.getReplyTimes() >= ladderReward.getReply().intValue();
				if (isReply && active.getGreetTimes() >= ladderReward.getGreetTimes()
						&& active.getOnlineTime() >= ladderReward.getOnlineTime()) {
					current = ladderReward;
				}
			}
			return current;
		}

		public LadderReward calcNextReward(Integer greetTimes, Integer replyTimes, Integer onlineTime, Gender gender) {
			List<LadderReward> ladderRewards = getLadderRewards();
			int last = -1;
			for (int i = 0; i < ladderRewards.size(); i++) {
				LadderReward ladderReward = ladderRewards.get(i);
				// 男用户是人数，女用户是百分比
				Integer reply = Gender.FEMALE == gender ? ladderReward.getReply().multiply(BigDecimal.valueOf(100)).intValue() : ladderReward.getReply().intValue();
				if (greetTimes >= ladderReward.getGreetTimes()
						&& replyTimes >= reply
						&& onlineTime >= ladderReward.getOnlineTime()) {
					last = i;
				}
			}
			if (last >= ladderRewards.size() - 1) {
				return ladderRewards.get(ladderRewards.size() - 1);
			} else {
				return ladderRewards.get(last + 1);
			}
		}

		public boolean isEnable(WesKit wesKit) {
			if (wesKitEnable == null || !enable) {
				return false;
			}
			return wesKitEnable.contains(wesKit);
		}

	}



	@Setter
	@Getter
	public static class ConsecutiveConfig {

		// 配置生效日期
		private TimeInterval interval;
		// 配置开关
		private boolean configSwitch;
		// 奖励等级列表
		private List<RewardLevel> rewardLevels;
		/** 启用的分包,不在次Set中的，分包用户不结算 */
		private Set<WesKit> wesKitEnable;

		/**
		 * 判断时间是否在区间内（包含边界）
		 *
		 * @param time 要检查的时间
		 * @return true 如果 time 在 start 和 end 之间（包含边界），否则 false
		 */
		public boolean isDateWithinInterval(Date time) {
			return !time.before(interval.getFinalBegin()) && !time.after(interval.getFinalEnd());
		}

		public boolean isEnable(WesKit wesKit) {
			if (wesKitEnable == null || !configSwitch) {
				return false;
			}
			return wesKitEnable.contains(wesKit);
		}

		public RewardLevel lastLevel() {
			return rewardLevels.get(rewardLevels.size() - 1);
		}

		public static ConsecutiveConfig getDefault() {
			// 创建默认的Milestone对象
			Milestone milestone1 = new Milestone();
			milestone1.setVideoTime(30);
			milestone1.setReward(300);
			milestone1.setIndex(1);

			Milestone milestone2 = new Milestone();
			milestone2.setVideoTime(50);
			milestone2.setReward(500);
			milestone2.setIndex(2);

			Milestone milestone3 = new Milestone();
			milestone3.setVideoTime(100);
			milestone3.setReward(800);
			milestone3.setIndex(3);

			Milestone milestone4 = new Milestone();
			milestone4.setVideoTime(120);
			milestone4.setReward(800);
			milestone4.setIndex(4);

			List<Milestone> milestones = Arrays.asList(milestone1, milestone2, milestone3, milestone4);
			// 创建默认的RewardLevel对象
			RewardLevel rewardLevel1 = new RewardLevel();
			rewardLevel1.setDays(3);
			rewardLevel1.setIndex(1);
			rewardLevel1.setMilestones(milestones);

			RewardLevel rewardLevel2 = new RewardLevel();
			rewardLevel2.setDays(5);
			rewardLevel2.setMilestones(milestones);
			rewardLevel2.setIndex(2);

			RewardLevel rewardLevel3 = new RewardLevel();
			rewardLevel3.setDays(7);
			rewardLevel3.setMilestones(milestones);
			rewardLevel3.setIndex(3);

			RewardLevel rewardLevel4 = new RewardLevel();
			rewardLevel4.setDays(30);
			rewardLevel4.setMilestones(milestones);
			rewardLevel4.setIndex(4);

			// 创建默认的Configuration对象
			ConsecutiveConfig defaultConfig = new ConsecutiveConfig();
			defaultConfig.setInterval(TimeInterval.of(new Date(), Calendar.MONTH));
			defaultConfig.setConfigSwitch(false);
			defaultConfig.setRewardLevels(Arrays.asList(rewardLevel1, rewardLevel2, rewardLevel3, rewardLevel4));

			return defaultConfig;
		}

		public RewardLevel getRewardLevel(int level) {
			int size = rewardLevels.size();
			if (size < level) {
				return null;
			}
			return rewardLevels.get(level - 1);
		}

	}

	@Setter
	@Getter
	public static class RewardLevel {

		// 天数
		private int days;
		// 里程碑列表
		private List<Milestone> milestones;
		// 当前阶梯
		private int index;

		public Milestone calcMilestone(Integer lastIndex, Integer videoMinute) {
			Milestone m = calcMilestone(videoMinute);
			if (m == null) {
				return m;
			}

			if (m.getIndex() <= lastIndex) {
				return m;
			}

			return milestones.get(lastIndex - 1);
		}

		public Milestone calcMilestone(Integer videoMinute) {
			Milestone m = null;
			for (Milestone milestone : milestones) {
				if (milestone.getVideoTime() <= videoMinute) {
					m = milestone;
				} else {
					break;
				}
			}
			return m;
		}

	}

	@Getter
	@Setter
	public static class Milestone {

		// 视频时长（分钟）
		private Integer videoTime;
		// 奖励（数量）
		private Integer reward;
		// 当前lv
		private int index;

	}

}
